package com.learn.springboot.controller.excel;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.learn.springboot.dao.dto.OrderDataExcelDto;
import com.learn.springboot.dao.dto.OrderRuleExcelDto;
import com.learn.springboot.dao.mode.ExportInfoVo;
import com.learn.springboot.service.order.ImportOrderExcelDataSheetListener;
import com.learn.springboot.service.order.ImportOrderExcelRuleSheetListener;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
@RequestMapping(value = "/api/import")
public class ExcelImportController extends AbstractExportBaseController {


    @RequestMapping("/order/deal")
    public void orderDealExcel(HttpServletResponse response, MultipartFile file,
                               String ruleSheet,
                               String dataSheet) throws IOException {
        if (file == null) {
            super.returnErrExportResponse(response, "文件不能为空");
        }
        ImportOrderExcelRuleSheetListener ruleSheetListener =
                new ImportOrderExcelRuleSheetListener();
        EasyExcel.read(Objects.requireNonNull(file).getInputStream(),
                        OrderRuleExcelDto.class, ruleSheetListener)
                .sheet(ruleSheet).headRowNumber(1)
                .doRead();

        ImportOrderExcelDataSheetListener dataSheetListener =
                new ImportOrderExcelDataSheetListener();
        EasyExcel.read(Objects.requireNonNull(file).getInputStream(),
                        OrderDataExcelDto.class, dataSheetListener)
                .sheet(dataSheet).headRowNumber(1)
                .doRead();

        List<Object> heads = dataSheetListener.getHeads();
        Map<String, List<OrderDataExcelDto>> dataSplitMap = new HashMap<>(10);
        Map<String, String> dataSheetNameMap = new HashMap<>(10);
        Set<String> md5Set = new HashSet<>();
        List<String> sortList = new ArrayList<>(10);
        dataSheetListener.getOrderDataExcelDtos().forEach(orderDataExcelDto -> {
            ruleSheetListener.getOrderRules().forEach(orderRuleExcelDto -> {

                if (DateUtil.isIn(orderDataExcelDto.getPayDt(), orderRuleExcelDto.getStartLiveTime(), orderRuleExcelDto.getEndLiveTime())) {
                    String md5 = MD5.create().digestHex(orderRuleExcelDto.toString());
                    List<OrderDataExcelDto> filterOrderDataList = dataSplitMap.getOrDefault(md5, new ArrayList<>());
                    if (filterOrderDataList.isEmpty()) {
                        String sheetName = StrUtil.format("{}_{}_{}",
                                orderRuleExcelDto.getTimeDtStr(), orderRuleExcelDto.getAccount(), orderRuleExcelDto.getTimeName());
                        dataSheetNameMap.put(md5, sheetName);
                        sortList.add(md5);
                    }
                    orderDataExcelDto.setRuleMd5(md5);
                    md5Set.add(orderDataExcelDto.getData().get(0).toString());
                    filterOrderDataList.add(orderDataExcelDto);
                    dataSplitMap.put(md5, filterOrderDataList);
                }
            });
        });

        // 未分类订单
        List<OrderDataExcelDto> notAddList = dataSheetListener.getOrderDataExcelDtos().stream()
                .filter(orderDataExcelDto -> !md5Set.contains(orderDataExcelDto.getData().get(0).toString()))
                .collect(Collectors.toList());

        List<ExportInfoVo> exportInfoVos = new ArrayList<>(10);


        sortList.forEach(md5 -> Optional.ofNullable(dataSplitMap.get(md5)).ifPresent(orderDataExcelDtos -> {
            ExportInfoVo exportInfoVo = new ExportInfoVo();
            List<List<Object>> dataList = new ArrayList<>();
            dataList.add(heads);
            orderDataExcelDtos.forEach(orderDataExcelDto -> {
                dataList.add(orderDataExcelDto.getData());
            });
            exportInfoVo.setDataList(dataList);
            exportInfoVo.setSheetName(dataSheetNameMap.get(orderDataExcelDtos.get(0).getRuleMd5()));
            exportInfoVo.setOutFileName("汇总订单结果");
            exportInfoVos.add(exportInfoVo);
        }));

        exportInfoVos.add(creatUnAddExportInfoVo(notAddList, heads));
        returnMultiSheetResponse(response, exportInfoVos);
    }

    private ExportInfoVo creatUnAddExportInfoVo(List<OrderDataExcelDto> notAddList, List<Object> heads) {
        ExportInfoVo exportInfoVo = new ExportInfoVo();
        List<List<Object>> dataList = new ArrayList<>();
        dataList.add(heads);
        notAddList.forEach(orderDataExcelDto -> {
            dataList.add(orderDataExcelDto.getData());
        });
        exportInfoVo.setDataList(dataList);
        exportInfoVo.setSheetName("自然流量订单");
        exportInfoVo.setOutFileName("汇总订单结果");
        return exportInfoVo;
    }

}
